package chat.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.SocketException;
import java.net.UnknownHostException;

import chat.client.statemachine.chat.AlgorithmChat;
import chat.client.statemachine.chat.ChatMessageContent;

/**
 * This class is the main of the chat client. It configures the client, connects
 * to a chat server, launches a thread for reading chat messages from the
 * standard input, and enters an infinite loop for receiving messages and
 * executing the corresponding action of the client's state machine.
 * 
 * @author chris
 * @author Denis Conan
 * 
 */
public class ChatClientMain {
	public static void main(final String[] argv) {
		ChatClientState cstate = new ChatClientState();
		ChatClient myClient;
		BufferedReader bufin;
		
		if (argv.length != 3) {
			System.out.println("usage: java chatClientMain"
					+ " <machine> <port> <identity>");
			return;
		}
		cstate.identity = Integer.parseInt(argv[2]);
		
		/* Init vector clock */
		cstate.localClock.setEntry(cstate.identity, 0);
		
		try {
			myClient = new ChatClient(argv[0], Integer.parseInt(argv[1]),
					cstate);
		} catch (SocketException se) {
			se.printStackTrace();
			return;
		} catch (UnknownHostException ue) {
			ue.printStackTrace();
			return;
		} catch (IOException ie) {
			ie.printStackTrace();
			return;
		}
		bufin = new BufferedReader(new InputStreamReader(System.in));
		// this thread will listen to incoming messages
		new Thread(myClient).start();
		// Main program reads from stdin and sendMessages
		while (true) {
			String s;
			long sent;
			// lecture d'une ligne et envoi tableau dataBuf
			try {
				s = bufin.readLine();
				if (s == null) {
					break;
				}
				/* Acquisition du sémaphore */
				try {
					cstate.semaphore.acquire();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				/* Incrément de l'horloge locale */
				/* vp[identify] = vp[identity] + 1 */
				cstate.localClock.incementEntry(cstate.identity);
				
				sent = myClient.sendMsg(AlgorithmChat.CHAT_MESSAGE
						.getActionIndex(), cstate.identity,
						new ChatMessageContent(cstate.identity, s, cstate.localClock));
				
				/* Relachement du sémaphore */
				cstate.semaphore.release();
			} catch (IOException ie) {
				ie.printStackTrace();
				break;
			}
			System.out.println(sent + " bytes sent.");
		}
		try {
			myClient.close();
		} catch (IOException ie) {
			ie.printStackTrace();
			return;
		}
	}
}
